package com.codegenerator.util;

import com.codegenerator.config.GeneratorConfig;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库工具类，用于获取表结构信息
 */
public class DatabaseUtils {

    /**
     * 获取数据库所有表信息
     */
    public static List<GeneratorConfig.TableConfig> getTableInfo(String url, String username, String password, String driverClassName) throws SQLException {
        Connection connection = null;
        try {
            // 加载驱动
            Class.forName(driverClassName);

            // 获取连接
            connection = DriverManager.getConnection(url, username, password);

            // 获取数据库元数据
            DatabaseMetaData metaData = connection.getMetaData();

            // 获取所有表
            String databaseName = getDatabaseName(url);
            ResultSet tables = metaData.getTables(databaseName, null, null, new String[]{"TABLE"});

            List<GeneratorConfig.TableConfig> tableConfigs = new ArrayList<>();

            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");
                String tableComment = tables.getString("REMARKS");

                GeneratorConfig.TableConfig tableConfig = createTableConfig(metaData, databaseName, tableName, tableComment);
                tableConfigs.add(tableConfig);
            }

            return tableConfigs;
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("数据库驱动加载失败: " + e.getMessage(), e);
        } finally {
            closeConnection(connection);
        }
    }

    /**
     * 获取单个表的信息
     * @param tableName 要获取信息的表名
     */
    public static GeneratorConfig.TableConfig getSingleTableInfo(String url, String username, String password, String driverClassName, String tableName) throws SQLException {
        Connection connection = null;
        try {
            // 加载驱动
            Class.forName(driverClassName);

            // 获取连接
            connection = DriverManager.getConnection(url, username, password);

            // 获取数据库元数据
            DatabaseMetaData metaData = connection.getMetaData();
            String databaseName = getDatabaseName(url);

            // 检查表是否存在
            ResultSet tables = metaData.getTables(databaseName, null, tableName, new String[]{"TABLE"});
            if (!tables.next()) {
                throw new IllegalArgumentException("表 " + tableName + " 不存在于数据库 " + databaseName + " 中");
            }

            String tableComment = tables.getString("REMARKS");

            // 创建并返回表配置
            return createTableConfig(metaData, databaseName, tableName, tableComment);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("数据库驱动加载失败: " + e.getMessage(), e);
        } finally {
            closeConnection(connection);
        }
    }

    /**
     * 创建表配置对象（抽取公共方法）
     */
    private static GeneratorConfig.TableConfig createTableConfig(DatabaseMetaData metaData, String databaseName, String tableName, String tableComment) throws SQLException {
        GeneratorConfig.TableConfig tableConfig = new GeneratorConfig.TableConfig();
        tableConfig.setTableName(tableName);
        tableConfig.setComments(tableComment);

        // 获取表的列信息
        List<GeneratorConfig.ColumnConfig> columnConfigs = getColumnInfo(metaData, databaseName, tableName);
        tableConfig.setColumns(columnConfigs);

        return tableConfig;
    }
    
    /**
     * 获取表的列信息
     */
    private static List<GeneratorConfig.ColumnConfig> getColumnInfo(DatabaseMetaData metaData, String databaseName, String tableName) throws SQLException {
        ResultSet columns = metaData.getColumns(databaseName, null, tableName, null);
        ResultSet primaryKeys = metaData.getPrimaryKeys(databaseName, null, tableName);
        
        List<GeneratorConfig.ColumnConfig> columnConfigs = new ArrayList<>();
        List<String> primaryKeyColumns = new ArrayList<>();
        
        // 获取主键列
        while (primaryKeys.next()) {
            primaryKeyColumns.add(primaryKeys.getString("COLUMN_NAME"));
        }
        
        // 获取列信息
        while (columns.next()) {
            String columnName = columns.getString("COLUMN_NAME");
            String dataType = columns.getString("TYPE_NAME");
            String columnComment = columns.getString("REMARKS");
            boolean isPrimaryKey = primaryKeyColumns.contains(columnName);
            
            GeneratorConfig.ColumnConfig columnConfig = new GeneratorConfig.ColumnConfig();
            columnConfig.setColumnName(columnName);
            columnConfig.setDataType(dataType);
            columnConfig.setColumnComment(columnComment);
            columnConfig.setPrimaryKey(isPrimaryKey);
            
            // 转换数据库类型为Java类型
            String javaType = getJavaType(dataType);
            columnConfig.setJavaType(javaType);
            
            // 判断是否自增（简单判断，实际可能需要更复杂的逻辑）
            columnConfig.setAutoIncrement("INT auto_increment".equalsIgnoreCase(dataType) || 
                                         "BIGINT auto_increment".equalsIgnoreCase(dataType));
            
            columnConfigs.add(columnConfig);
        }
        
        return columnConfigs;
    }
    
    /**
     * 从URL中获取数据库名称
     */
    private static String getDatabaseName(String url) {
        if (url.contains("?")) {
            url = url.substring(0, url.indexOf("?"));
        }
        return url.substring(url.lastIndexOf("/") + 1);
    }
    
    /**
     * 将数据库类型转换为Java类型
     */
    private static String getJavaType(String dbType) {
        dbType = dbType.toUpperCase();
        
        if (dbType.contains("VARCHAR") || dbType.contains("CHAR") || dbType.contains("TEXT")) {
            return "String";
        } else if (dbType.contains("INT") || dbType.contains("INTEGER")) {
            return "Integer";
        } else if (dbType.contains("BIGINT")) {
            return "Long";
        } else if (dbType.contains("FLOAT") || dbType.contains("DOUBLE") || dbType.contains("DECIMAL")) {
            return "Double";
        } else if (dbType.contains("DATE") || dbType.contains("TIME") || dbType.contains("TIMESTAMP")) {
            return "java.util.Date";
        } else if (dbType.contains("BOOLEAN") || dbType.contains("BIT")) {
            return "Boolean";
        } else if (dbType.contains("BLOB") || dbType.contains("BYTE")) {
            return "byte[]";
        }
        
        // 默认返回String
        return "String";
    }

    /**
     * 关闭数据库连接
     */
    private static void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // 忽略关闭连接异常
                e.printStackTrace();
            }
        }
    }
}
